package balmysundaycandy.more.low.level.logger;

import java.util.concurrent.Future;

import balmysundaycandy.more.low.level.logger.impl.XmppLogger;

import com.google.apphosting.api.ApiProxy;
import com.google.apphosting.api.ApiProxy.ApiConfig;
import com.google.apphosting.api.ApiProxy.ApiProxyException;
import com.google.apphosting.api.ApiProxy.Environment;
import com.google.apphosting.api.ApiProxy.LogRecord;

/**
 * delegate send rpc call detail by xmpp.
 * 
 * @author marblejenka
 * 
 */
public class ProtocolBufferLogDelegate implements ApiProxy.Delegate<Environment> {

	private final ProtocolBufferLogger protocolBufferLogger;

	@SuppressWarnings("unchecked")
	private static final ApiProxy.Delegate<Environment> original = ApiProxy.getDelegate();

	@Override
	public void log(Environment environment, LogRecord logRecord) {
		getOriginal().log(environment, logRecord);
	}

	public ProtocolBufferLogDelegate(String sendaddress) {
		// xmpp is defalut
		this.protocolBufferLogger = new XmppLogger(sendaddress);
	}
	
	public ProtocolBufferLogDelegate(ProtocolBufferLogger protocolBufferLogger) {
		this.protocolBufferLogger = protocolBufferLogger;
	}
	
	public static ApiProxy.Delegate<Environment> getOriginal() {
		return original;
	}

	@Override
	public byte[] makeSyncCall(Environment environment, String serviceName, String methodName, byte[] request) throws ApiProxyException {
		if ("xmpp".equals(serviceName)) {
			// ignore xmpp rpc call
			return original.makeSyncCall(environment, serviceName, methodName, request);
		}

		// rpc call
		byte[] result = original.makeSyncCall(environment, serviceName, methodName, request);

		ProtocolBufferKey key = new ProtocolBufferKey(serviceName, methodName);
		if (ProtocolBufferObjectHolder.protocolmessagerequests.containsKey(key)) {
			protocolBufferLogger.log(new ProtocolBufferLogContents().key(key).request(request).response(result));
		}

		return result;
	}

	@Override
	public Future<byte[]> makeAsyncCall(Environment environment, String serviceName, String methodName, byte[] request, ApiConfig apiConfig) {
		return original.makeAsyncCall(environment, serviceName, methodName, request, apiConfig);
	}

}